iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

寫程式帶給我的無形快樂系列 第 21 篇

吃下 Regular Expressions 翻譯年糕 (環顧四周)

  • 分享至 

  • xImage
  •  

有些時候想要匹配的規則,會想知道該位置的前後字元是否有符合我們想要的規則

有種像是告訴 Regex Engine 説:
你先幫我找到 X,找到後再幫我看看它的前面有沒有 Y,或是它的後面有沒有 Z

這樣環顧四周的行為分成 Lookahead 和 Lookbehind 兩種


Lookahead

網路上翻作 先行斷言

X(?=Y) 代表要找 X,而且後面要跟著 Y 的我才要

當 Regex Engine 運作時,它會先找到 X的位置,接著再檢查是否有 Y 緊跟著

也可以用 Negative Lookahead,代表後面不要接著某某字元,例如: (?!foo)


Lookbehind

網路上翻作 後行斷言

注意: 在非 V8 Engine 的瀏覽器,像是 Safari IE 是不支援 Lookbehind 的!!

和 Lookahead 類似,Lookbehind 會幫我們回溯一個字元看

例如 (?<=Y)X 代表幫我找到 X,但X 左側要是 Y
一樣也可以使用 Negative Lookbehind,例如: (?<!foo)


練習

範例取自 Lookahead and lookbehind

試著找出字串中不為負數的整數出來

let regexp = /your regexp/g;

let str = "0 12 -5 123 -18";

alert( str.match(regexp) ); // 0, 12, 123

找出不為負數的規則是:

  1. 找出數字 (最大不限幾位數,至少為個位數)
  2. 且該數字的左側 (Lookbehind) 不為負號

翻譯年糕:

目標要找出 \d 數字,而且數字的數量不設上限+,至少出現一次以上
數字的左側不得為負號 (?<!-)

第一次可能會這樣寫 /(?<!-)\d+/g
會發現 -18的 8 也被匹配到
因為 『 數字的左側不得為負號 』這個規則,應該是指數字的第一位數左側不為負號

可以改成 /(?<![-\d])\d+/g

或是我會改成 /(?<!-)\b\d+/g 多加一個 \b ,數字開頭要為單詞邊界


小結

pattern 是從文本的左至右去做匹配

往右側的下一個字元看 --> Lookahead
往左側的上一個字元看 --> Lookbehind

Pattern 說明 Match 例子
X(?=Y) X 後面接著 Y XY
X(?!Y) X 後面不要接著 Y XZ
(?<=Y)X X 前面是 Y YX
(?<!Y)X X 前面不是 Y ZX

以上匹配到的都是 X, 並不包含 () 內的內容

() 中寫的 Lookahead或是 Lookbehind 是不佔位不佔位的!

預告下一篇,迎接 Regular Expressions 年糕最後一口, Regex Engine !


上一篇
吃下 Regular Expressions 翻譯年糕 (位置)
下一篇
吃下 Regular Expressions 翻譯年糕 (Regex Engine)
系列文
寫程式帶給我的無形快樂 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言